package com.itgaohe.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itgaohe.common.context.UserContext;
import com.itgaohe.dao.entity.SeckillVoucher;
import com.itgaohe.dao.entity.Voucher;
import com.itgaohe.dao.entity.VoucherOrder;
import com.itgaohe.dao.mapper.VoucherMapper;
import com.itgaohe.dao.mapper.VoucherOrderMapper;
import com.itgaohe.dto.UserDTO;
import com.itgaohe.service.UserService;
import com.itgaohe.service.VoucherOrderService;
import com.itgaohe.service.VoucherService;
import com.itgaohe.utils.RedisIdWork;
import com.itgaohe.utils.Result;
import lombok.RequiredArgsConstructor;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
@RequiredArgsConstructor
public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements VoucherOrderService {
    final private VoucherOrderMapper voucherOrderMapper;
    final private VoucherMapper voucherMapper;
    final private RedisIdWork redisIdWork;
    /*
    普通优惠券订单创建
     */
    @Override
    public Result createNormalVoucherOrder(Long voucherId) {
        // 1. 验证优惠券有效性
        Voucher voucher = voucherMapper.selectAvailableVoucherById(voucherId);
        if (voucher == null) {
            return Result.fail("优惠券不存在或已下架");
        }
        if (voucher.getType() != 0) {
            return Result.fail("非普通券类型");
        }
        // 2. 获取当前用户id
        Long userId = UserContext.getUser().getId();
        //3.校验购买资格（一人一单）
        int orderCount = voucherOrderMapper.countUserOrders(userId, voucherId);
        if (orderCount > 0) {
            return Result.fail("您已购买过该优惠券");
        }

        // 3. 创建订单对象
        VoucherOrder order = new VoucherOrder();
        order.setUserId(userId);
        order.setVoucherId(voucherId);
        order.setPayType(1); // 默认余额支付
        order.setStatus(1);  // 未支付

        // 4. 插入数据库
        int insert = voucherOrderMapper.insert(order);
        if (insert != 1) {
            Result.fail("购买失败") ;
        }

        return Result.ok(order.getId());

    }

    /*
    秒杀券订单创建
     */
    @Override
    public Result createSeckillVoucherOrder(Long voucherId) {


        // 1. 查询并校验秒杀券
        SeckillVoucher voucher = voucherMapper.selectForUpdate(voucherId);
        if (voucher == null) {
            return Result.fail("秒杀券不存在");
        }

        // 2. 校验秒杀时间
        LocalDateTime now = LocalDateTime.now();
        if (now.isBefore(voucher.getBeginTime())) {
            return Result.fail("秒杀尚未开始");
        }
        if (now.isAfter(voucher.getEndTime())) {
            return Result.fail("秒杀已结束");
        }

        // 3. 校验库存
        if (voucher.getStock() <= 0) {
            return Result.fail("库存不足");
        }

        Long userId = UserContext.getUser().getId();
        synchronized (userId.toString().intern()) {
            //获取代理对象（事务）
            VoucherOrderService proxy =(VoucherOrderService) AopContext.currentProxy();
            return proxy.seckillVoucherOrder(voucherId);
        }
    }
    @Transactional
    public Result seckillVoucherOrder(Long voucherId) {

        // 4. 获取当前用户id
        Long userId = UserContext.getUser().getId();

        // 5. 校验购买资格（一人一单）
        int orderCount = voucherOrderMapper.countUserOrders(userId, voucherId);
        if (orderCount > 0) {
            return Result.fail("您已购买过该秒杀券");
        }

        // 6. 扣减库存
        int updateCount = voucherMapper.deductStock(voucherId);
        if (updateCount == 0) {
            return Result.fail("库存不足");
        }

        // 7. 创建订单
        VoucherOrder order = new VoucherOrder();
        Long orderId = redisIdWork.nextId("order");
        //订单id
        order.setId(orderId);
        //用户id
        order.setUserId(userId);
        //优惠券id
        order.setVoucherId(voucherId);
        order.setPayType(1); // 默认余额支付
        order.setStatus(1);  // 未支付
        //插入数据
        voucherOrderMapper.insert(order);
        //8.返回订单id
        return Result.ok(orderId);
    }
}
